package com.sixfoot.service;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import io.netty.channel.ChannelHandlerContext;

/**
 * 服务器管理类
 * 
 * @author six-foot
 *
 */
public class ServerManager {
	// 缓存所有登录用户对应的通信上下文环境（主要用于业务数据处理）
	private static Map<String, ChannelHandlerContext> USER_CHANNEL_MAP = new ConcurrentHashMap<>();
	// 缓存通信上下文环境对应的登录用户（主要用于服务）
	private static Map<ChannelHandlerContext, String> CHANNEL_USER_MAP = new ConcurrentHashMap<>();
	
	/**
	 * 给单个用户发送消息
	 * @param pact 消息
	 * @param userId 用户ID
	 */
	public static void sendPacketTo(Object pact, String userId) {
		if (pact == null || userId == null || userId.equals(""))
			return;

		Map<String, ChannelHandlerContext> contextMap = USER_CHANNEL_MAP;
		if (contextMap.isEmpty())
			return;

		ChannelHandlerContext targetContext = contextMap.get(userId);
		if (targetContext == null)
			return;

		targetContext.writeAndFlush(pact);
	}

	/**
	 * 向所有在线用户发送数据包
	 * @param pact 消息
	 */
	public static void sendPacketToAllUsers(Object pact) {
		if (pact == null)
			return;
		Map<String, ChannelHandlerContext> contextMap = USER_CHANNEL_MAP;
		if (contextMap.isEmpty())
			return;

		contextMap.values().forEach((ctx) -> ctx.writeAndFlush(pact));
	}

	/**
	 * 向单一在线用户发送数据包
	 * @param pact 
	 * @param targetContext 
	 */
	public static void sendPacketTo(Object pact, ChannelHandlerContext targetContext) {
		if (pact == null || targetContext == null)
			return;
		targetContext.writeAndFlush(pact);
	}

	/**
	 * 通过用户ID查询 信道处理器上下文
	 * @param userId
	 * @return
	 */
	public static ChannelHandlerContext getOnlineContextBy(String userId) {
		return USER_CHANNEL_MAP.get(userId);
	}

	/**
	 * 增加在线用户
	 * @param userId
	 * @param context
	 */
	public static void addOnlineContext(String userId, ChannelHandlerContext context) {
		if (context == null) {
			throw new NullPointerException();
		}
		USER_CHANNEL_MAP.put(userId, context);
		CHANNEL_USER_MAP.put(context, userId);
	}

	/**
	 * 注销用户通信渠道
	 * @param context
	 */
	public static void ungisterUserContext(ChannelHandlerContext context) {
		if (context != null) {
			String userId = CHANNEL_USER_MAP.getOrDefault(context, "");
			CHANNEL_USER_MAP.remove(context);
			USER_CHANNEL_MAP.remove(userId);
			context.close();
		}
	}
}
